package top.dotgo.web.base.ext;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.SneakyThrows;
import top.dotgo.kit.Const;

import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author jornl
 * @date 2020/3/12 15:56 星期四
 */
public class DotConst {
    public static final String TITLE = "title";
    public static final String NAME = "name";
    public static final String V = "v";
    private static final LinkedHashMap<String, JSON> ALL_CONST = new LinkedHashMap<>();
    @Getter
    private static String md5 = "0";

    private DotConst() {
    }

    @SneakyThrows
    private static void load() {
        Class<?>[] enumArr = Const.class.getDeclaredClasses();
        for (Class<?> clazz : enumArr) {
            //跳过 enum 和 baseEnum
            if (clazz.isAssignableFrom(Const.BaseEnum.class) || clazz.isAssignableFrom(Const.Enum.class)) {
                continue;
            }
            //如果是 枚举
            if (clazz.isEnum()) {
                ALL_CONST.put(clazz.getSimpleName(), getEnumList(clazz));
            }
            //如果是 接口
            if (clazz.isInterface()) {
                JSONObject object = new JSONObject();
                Class<?>[] tempArr = clazz.getDeclaredClasses();
                //加载公共字段
                Field[] fields = clazz.getDeclaredFields();
                JSONArray pubArray = new JSONArray();
                for (Field field : fields) {
                    Const.Enum em = (Const.Enum) field.get(clazz);
                    pubArray.add(new JSONObject().fluentPut(V, em.v).fluentPut(NAME, field.getName()).fluentPut(TITLE, em.title));
                }

                for (Class<?> tempClazz : tempArr) {
                    object.put(tempClazz.getSimpleName(), getEnumList(tempClazz).fluentAddAll(pubArray));
                }
                ALL_CONST.put(clazz.getSimpleName(), object);
            }
        }
        md5 = SecureUtil.md5(JSON.toJSONString(ALL_CONST));
    }

    /**
     * 获取常量
     *
     * @return LinkedHashMap<String, JSON>
     */

    public static Map<String, JSON> getAllConst() {
        if (ALL_CONST.isEmpty()) {
            load();
        }
        return ALL_CONST;
    }

    /**
     * 根据 enum类 解析称 json对象
     *
     * @param clazz clazz
     * @return JSONArray
     */

    @SuppressWarnings({"unchecked", "rawtypes"})
    private static JSONArray getEnumList(Class clazz) {
        JSONArray array = new JSONArray();
        LinkedHashMap<String, ?> tempMap = EnumUtil.getEnumMap(clazz);
        for (Map.Entry<String, ?> entry : tempMap.entrySet()) {
            JSONObject json = new JSONObject();
            Object obj = entry.getValue();
            json.put(V, BeanUtil.getFieldValue(obj, V));
            json.put(NAME, BeanUtil.getFieldValue(obj, NAME));
            json.put(TITLE, BeanUtil.getFieldValue(obj, TITLE));
            array.add(json);
        }
        return array;
    }

}
